#include "random.h"
/*
void Random::getSeed(uint32_t seed)
{
	SEED = seed;
}
*/

Mersenne_Twister::Mersenne_Twister(uint32_t seed)
{
	W = 32;
	N = 624;
	M = 397;
	R = 31;
	A = 0x9908b0df;
	U = 1;;
	S = 7;
	B = 0x9d2c5680;
	T = 15;
	C = 0xefc60000;
	L = 18;
	INDEX = 0;
	SEED = seed;
	initializeGenerator();
}


// Initialize the generator from a seed
void Mersenne_Twister::initializeGenerator()
{
	MT[0] = SEED;
	for (int i=1; i<NUM_MAX; i++)
	{
		MT[i] = (1812433253 * (MT[i-1] ^ (MT[i-1] >> 30))) + i;
	}
}

// Generate an array of 624 untempered numbers
void Mersenne_Twister::generateNumbers()
{
	int i, y;
	for (i=0; i<NUM_MAX; i++)
	{
		y = ((MT[i]>>31)<<31) + ((MT[(i+1)%NUM_MAX]<<1)>>1);
		MT[i] = MT[(i+397)%NUM_MAX] ^ (y>>1);
		if ((y%2)==1)
			MT[i] ^= 2567483615;
	}
}

void Mersenne_Twister::getSeed(uint32_t seed)
{
	SEED = seed;
}


// Extract a tempered pseudorandom number based on the index-th value, calling generateNumbers() every 624 numbers
uint32_t Mersenne_Twister::rand()
{
	if (INDEX == 0)
		generateNumbers();
	
	uint32_t y = MT[INDEX];
	y ^= (y >> 11);
	y ^= (y << 7 ) & 2636928640;
	y ^= (y << 15) & 4022730752;
	y ^= (y >> 18);
	INDEX = ++INDEX % NUM_MAX;
	return y;
}
